Registering a COM Server


HKEY_CLASSES_ROOT/CLSID

A COM server must be included in Windows registry so that it can work. The figure below shows Windows Registry for a COM server.
Un servidor COM debe estar incluido en el registro de Windows para que este pueda operar. La figura de abajo muestra el registro de Windows para un servidor COM.

CLSID

Key Access

When opening a key in Windows Registry, you must indicate the desired access. If you are not going to modify the registry, you must open the key using KEY_READ. The following values for the key access can be used:
  • KEY_READ
  • KEY_WRITE
  • KEY_SET_VALUE
  • KEY_CREATE_SUB_KEY
  • KEY_EXECUTE
  • KEY_ALL_ACCESS

Cuando se abre una llave en el registro de Windows usted debe indicar el acceso deseado. Si usted no va a modificar el registro de Windows, usted debe abrir la llave usando KEY_READ. Los siguientes son los valores que puede tener el acceso de una llave:
  • KEY_READ
  • KEY_WRITE
  • KEY_SET_VALUE
  • KEY_CREATE_SUB_KEY
  • KEY_EXECUTE
  • KEY_ALL_ACCESS

Problem 1
Create a Wintempla application called MyRegServer to register the file C:\Users\selo\MyDesign.dll which hosts a COM server with the following information:
  • GUID: {808FAFE1-1B3C-4013-B0BC-2B02AB788807}
  • Caption: MyDesign Class
  • ProgID: Selo.MyDesign.1
  • VersionIndependentProgID: Selo.MyDesign
As this program modifies the Windows registry, you must run Microsoft Visual Studio as Administrator, or run the program executable from the Debug (or Release) folder as Administrator.
Cree una aplicación de Wintempla llamada MyRegServer para registrar el archivo C:\Users\selo\MyDesign.dll el cual hospeda un servidor COM con la siguiente información:
  • GUID: {808FAFE1-1B3C-4013-B0BC-2B02AB788807}
  • Caption: MyDesign Class
  • ProgID: Selo.MyDesign.1
  • VersionIndependentProgID: Selo.MyDesign
Como este programa modifica el registro de Windows, usted debe ejecutar Microsoft Visual Studio como Administrador, o ejecutar el archivo ejecutable desde la carpeta de Debug (o Release) como Administrador.

RunAsAdministrator

MyRegServer.cpp
...
void MyRegServer::Window_Open(Win::Event& e)
{
     const wchar_t * filename = L"C:\\Users\\selo\\MyDesign.dll ";
     const wchar_t* clsid = L"{808FAFE1-1B3C-4013-B0BC-2B02AB788807}";
     const wchar_t* caption= L"MyDesign Class";
     const wchar_t* ProgID = L"Selo.MyDesign.1";
     const wchar_t* VersionIndependentProgID = L"Selo.MyDesign";

     //_______________________________________________________ Open HKEY_CLASSES_ROOT/CLSID
     Sys::RegistryKey keyCLSID;
     if (keyCLSID.Open(HKEY_CLASSES_ROOT, L"CLSID", KEY_ALL_ACCESS) == false)
     {
          this->MessageBox(L"Error: Open HKEY_CLASSES_ROOT/CLSID", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     //_________________________________________________________ Create{clsid}
     Sys::RegistryKey keyGuid;
     if (keyCLSID.CreateSubKey(clsid, KEY_ALL_ACCESS, keyGuid) == false)
     {
          this->MessageBox(L"Error: Create HKEY_CLASSES_ROOT/CLSID/{guid}", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     // Set default value
     if (keyGuid.SetValue(NULL, caption) == false)
     {
          this->MessageBox(L"Error: Set default value HKEY_CLASSES_ROOT/CLSID/{guid}", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     //_______________________________________________________ Create InprocServer32
     Sys::RegistryKey keyInprocServer32;
     if (keyGuid.CreateSubKey(L"InProcServer32", KEY_ALL_ACCESS, keyInprocServer32) == false)
     {
          this->MessageBox(L"Error: Create HKEY_CLASSES_ROOT/CLSID/{guid}/InprocServer32", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     // Set default value
     if (keyInprocServer32.SetValue(NULL, filename) == false)
     {
          this->MessageBox(L"Error: Set default value HKEY_CLASSES_ROOT/CLSID/{guid}/keyInprocServer32", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     //________________________________________________________ ProgID
     Sys::RegistryKey keyProgID;
     if (keyGuid.CreateSubKey(L"ProgID", KEY_ALL_ACCESS, keyProgID) == false)
     {
          this->MessageBox(L"Error: Create HKEY_CLASSES_ROOT/CLSID/{guid}/ProgID", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     // Set default value
     if (keyProgID.SetValue(NULL, ProgID) == false)
     {
          this->MessageBox(L"Error: Set default value HKEY_CLASSES_ROOT/CLSID/{guid}/ProgID", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     //________________________________________________________VersionIndependentProgID
     Sys::RegistryKey keyVersionIndependentProgID;
     if (keyGuid.CreateSubKey(L"VersionIndependentProgID", KEY_ALL_ACCESS, keyVersionIndependentProgID) == false)
     {
          this->MessageBox(L"Error: Create HKEY_CLASSES_ROOT/CLSID/{guid}/VersionIndependentProgID", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
     // Set default value
     if (keyVersionIndependentProgID.SetValue(NULL, VersionIndependentProgID) == false)
     {
          this->MessageBox(L"Error: Set default value HKEY_CLASSES_ROOT/CLSID/{guid}/VersionIndependentProgID", L"MyRegServer", MB_OK | MB_ICONERROR);
          return;
     }
}


RegistryGuid

InprocServer32

ProgID

VersionIndependentProgID

Tip
You may use the functions: Com::Base::RegisterComClass and Com::Base::UnRegisterComClass to register and remove respectively from the registry a COM class as shown in the following code.
Usted puede usar las funciones: Com::Base::RegisterComClass y Com::Base::UnRegisterComClass para registrar y remover respectivamente del registro una clase COM como se muestra en el siguiente código.

MyServer.dll
void RegisterServer(HINSTANCE hInstance)
{
     const wchar_t* libid = L"{2DE03C33-6A5F-46A0-8692-D294422647DC}";
     const wchar_t* clsid = L"{808FAFE1-1B3C-4013-B0BC-2B02AB788807}";
     const wchar_t* companyName = L"Selo";
     const wchar_t* className = L"MyDesign";
     const int version = 1;
     HRESULT hr = Com::Base::RegisterServer(hInstance, libid, clsid, companyName, className, version);
     if (FAILED(hr))
     {
          ::MessageBox(NULL, Com::Exception::GetErrorDescr(hr), L"MyRegServer", MB_OK | MB_ICONERROR);
     }
}


Problem 2
Create a Wintempla application called RemoveServer to remove the COM class of previous problem from Windows registry.
Cree una aplicación de Wintempla llamada RemoveServer para remover la clase COM del problema previo del registro de Windows.

RemoveServer.cpp
...
void RemoveServer::Window_Open(Win::Event& e)
{
     const wchar_t* clsid = L"{808FAFE1-1B3C-4013-B0BC-2B02AB788807}";
     //_______________________________________________________ Open HKEY_CLASSES_ROOT/CLSID
     Sys::RegistryKey keyCLSID;
     if (keyCLSID.Open(HKEY_CLASSES_ROOT, L"CLSID", KEY_ALL_ACCESS) == false)
     {
          this->MessageBox(L"Error: Open HKEY_CLASSES_ROOT/CLSID", L"RemoveServer", MB_OK | MB_ICONERROR);
          return;
     }
     //________________________________________________________ Delete {clsid}/InprocServer32
     wstring text(clsid);
     text += L"\\InprocServer32";
     if (keyCLSID.DeleteSubKey(text.c_str()) == false)
     {
          this->MessageBox(L"Error: Delete \\InprocServer32", L"RemoveServer", MB_OK | MB_ICONERROR);
          return;
     }
     //________________________________________________________ Delete {clsid}/ProgID
     text = clsid;
     text += L"\\ProgID";
     if (keyCLSID.DeleteSubKey(text.c_str()) == false)
     {
          this->MessageBox(L"Error: Delete \\ProgID", L"RemoveServer", MB_OK | MB_ICONERROR);
          return;
     }
     //________________________________________________________ Delete {clsid}/VersionIndependentProgID
     text = clsid;
     text += L"\\VersionIndependentProgID";
     if (keyCLSID.DeleteSubKey(text.c_str()) == false)
     {
          this->MessageBox(L"Error: Delete \\VersionIndependentProgID", L"RemoveServer", MB_OK | MB_ICONERROR);
          return;
     }
     //________________________________________________________ Delete {clsid}
     if (keyCLSID.DeleteSubKey(clsid) == false)
     {
          this->MessageBox(L"Error: Delete {clsid}", L"RemoveServer", MB_OK | MB_ICONERROR);
          return;
     }
}


Tip
There are other keys that need to be created in Windows registry for the COM server to work. Specifically in the example of the previous problem, we also need to create:
  • HKEY_CLASSES_ROOT\Selo.MyDesign (default MyDesign Class)
  • HKEY_CLASSES_ROOT\Selo.MyDesign\CurVer (default Selo.MyDesign.1)
  • HKEY_CLASSES_ROOT\Selo.MyDesign.1 (default MyDesign Class)
  • HKEY_CLASSES_ROOT\Selo.MyDesign.1\CLSID (default {clsid})

Hay otras llaves que necesitan ser creadas en el registro de Windos para que el servidor COM trabaje. Específicamente en el ejemplo del problema previo nosotros también necesitamos crear:
  • HKEY_CLASSES_ROOT\Selo.MyDesign (default MyDesign Class)
  • HKEY_CLASSES_ROOT\Selo.MyDesign\CurVer (default Selo.MyDesign.1)
  • HKEY_CLASSES_ROOT\Selo.MyDesign.1 (default MyDesign Class)
  • HKEY_CLASSES_ROOT\Selo.MyDesign.1\CLSID (default {clsid})

© Copyright 2000-2021 Wintempla selo. All Rights Reserved. Jul 22 2021. Home